#pragma once 
#include<time.h>
#include <stdarg.h>
#include<stdio.h> 
#include<iostream>
#include<string>
 #include <cerrno>
#include<cstring> 
#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4
#define SIZE 1024



#define Screen 1  //往显示器上打印
#define Onefile 2//往一个文件上打印
#define Classfile 3   //分类打印

#define LogFile "log.txt"



class Log
{
    public:
    Log()
    {
        printMethod =Screen;
          path = "/home/cxq/lesson28/";
    }
      void Enable(int method)
    {
        printMethod = method;
    }
std::string levelToString ( int level)
{
    switch(level)
    {
            case Info :
        return "info" ;
        case Debug:
                return "Debug";
            case Warning:
                return "Warning";
            case Error:
                return "Error";
            case Fatal:
                return "Fatal";
            default  :
            return "None" ;
    }
}

// void logmessage (int level , const char * format , ...)  //...可变参数 
// {
//     //日志时间
//       time_t t=  time( nullptr);

//    struct tm* ctime = localtime(&t);
//       char leftbuffer[SIZE] ;
//       snprintf(leftbuffer,sizeof ( leftbuffer) ,  "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),
//                  ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,
//                  ctime->tm_hour, ctime->tm_min, ctime->tm_sec);
    

//       char rightbuffer[SIZE] ;
//       va_list s ;
//       va_start (s,format);

//       vsnprintf(rightbuffer ,sizeof( rightbuffer) , format , s) ;
//       va_end(s);

//     char logtxt[SIZE*2] ; 
//     snprintf(logtxt , sizeof(logtxt )  , "%s %s\n", leftbuffer,rightbuffer);


//     printLog(level, logtxt); //打印


// }

void printLog(int level,  const std::string &logtxt) 
{
  switch(printMethod)
  {
   case Screen :
      std::cout << logtxt << std::endl;
   break; 

    case Onefile:
            printOneFile(LogFile, logtxt);
            break;
      case Classfile:
            printClassFile(level, logtxt);
            break;
        default:
            break;
  }

}


void printOneFile(  const std::string &logname ,const std::string & logtxt)

{

   
  std::string   _logname = path+logname;  //路径 

// 在_logname这个路径下 ,打开一个文件，并把logtxt文件内容 ，往打开的文件里面写
int fd  = open( _logname.c_str() , O_CREAT|O_APPEND| O_WRONLY , 0666 ) ; 
 if (fd < 0)
            return;

write(fd ,logtxt.c_str(),logtxt.size()) ;

close (fd);


}

 void operator() (int level, const char *format, ...)
 {
      time_t t = time(nullptr)  ;
      struct tm * ctime= localtime (& t) ;
       char leftbuffer[SIZE]; 
    
     //将可变参数的类容输入到leftbuffer
    snprintf(leftbuffer,sizeof(leftbuffer) ,"[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),
                 ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,
                 ctime->tm_hour, ctime->tm_min, ctime->tm_sec);


                 va_list _s ;
                 va_start (_s,format);
                   char rightbuffer[SIZE];
                   //将可变参数的类容输入到rightbuffer
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, _s);
          va_end(_s);

             // 格式：默认部分+自定义部分
        char logtxt[SIZE * 2];
        //将leftbuffer和leftbuffer 输入到logtxt中
        snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, leftbuffer);

         // 打印logtxt
        printLog(level, logtxt);
    
 }


 void printClassFile(int level, const std::string &logtxt)
 {
      std::string filename = LogFile;
      filename +=  ".";
      filename += levelToString(level); // "log.txt.Debug/Warning/Fatal"
      printOneFile(filename, logtxt);



 } 

  ~Log()
    {
    }
  private:

     int printMethod;  //打印风格
    std::string path;//路径 

};